/*
 * Created on 2005-5-16
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package com.haoxi.gateway.runner;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.haoxi.gateway.common.Queue;

import java.util.Date;

/**
 * @author Cloud
 * Preferences - Java - Code Style - Code Templates
 */

public abstract class AbsOutQueue implements IRun {
    /**
     * Logger for this class
     */
    private static final Log log = LogFactory
            .getLog(AbsOutQueue.class);
    
    
    public static final int PROC_NORMAL = 2;
    
    public static final int PROC_RETRY = 4;
    
    public static final int PROC_ERROR = 8;
    
    private Queue queue;
    
    private boolean running = false;
    private int run_stat = IRun.RUNNER_READY;
    
    private Date createTime;
    private Date lastRunTime;
    private long sleepTime = 10 * 1000;  //sleep or wait time
    
    private String name;
    
    private AbsOutQueue(){}
    
    public AbsOutQueue(Queue inQueue) {
        queue = inQueue;
        createTime = new Date();
    }
    
    public void run() {
        log.debug("Out Queue:" + name + " start !!!");
        
        //check queue
        if(queue == null) {
            return;
        }
        
        //prepare running
        queue.addChengeListener(this);
        running = true;
        lastRunTime = new Date();
        
        int proc_status = PROC_ERROR;
        Object obj;
        while (running) {
            run_stat = IRun.RUNNER_RUNNING;
            lastRunTime.setTime(System.currentTimeMillis()); 
            obj = null;
            
            try { 
                int queueLen=0;
                synchronized (queue) {
                   obj = queue.sub();
                   queueLen=queue.getLength();
                }
                
                if (obj != null) {
                    proc_status = doJob(obj,queueLen);
                    
                    if(proc_status == PROC_RETRY) {
                        queue.add(obj);
                    }
                } else {
                    log.debug(queue.getName() + " is empty, sleep Zzz...");
                    synchronized(this) {
                        run_stat = IRun.RUNNER_WAITING;
                        wait(sleepTime);
                    }
                }
            } catch (InterruptedException e) {
                log.debug("////////////// wake up ///////////////");
            } catch (Exception e) {
                log.error("", e);
            }
        }//end of while
        running = false;
        run_stat = IRun.RUNNER_DEAD;
        queue.removeChengeListener(this);
        
        log.debug("Out Queue:" + name + " ended !!!");
    }
    
    
    public abstract int doJob(Object pObject, int queueLen);

    
    
    public Date getCreateTime() {
        return createTime;
    }

    public Date getLastRunTime() {
        return lastRunTime;
    }

    public long getSleepTime() {
        return sleepTime;
    }

    public int getStatus() {
        return run_stat;
    }

    public boolean isRunning() {
        return running;
    }

    public void setSleepTime(long lsleepTime) {
        sleepTime = lsleepTime;
    }

    public void setStop() {
        running = false;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
